package com.luhuiguo.cms.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.GlobalConstants;
import com.luhuiguo.cms.client.GlobalMessages;
import com.luhuiguo.cms.shared.event.AddArticleEvent;
import com.luhuiguo.cms.shared.event.ArticlesDeletedEvent;
import com.luhuiguo.cms.shared.event.ArticlesDeletedEventHandler;
import com.luhuiguo.cms.shared.event.EditArticleEvent;
import com.luhuiguo.cms.shared.model.ArticleListModel;
import com.luhuiguo.cms.shared.model.ChannelTreeModel;
import com.luhuiguo.cms.shared.rpc.ClearCache;
import com.luhuiguo.cms.shared.rpc.ClearCacheResult;
import com.luhuiguo.cms.shared.rpc.RemoveArticles;
import com.luhuiguo.cms.shared.rpc.RemoveArticlesResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetPresenter;

public class ArticlesPresenter extends WidgetPresenter<ArticlesPresenter.Display> {

    public interface Display extends WidgetDisplay {

        Button getAddButton();

        Button getDeleteButton();

        Button getClearCacheButton();

        Grid<BeanModel> getGrid();

        void reloadData();
    }

    private DispatcherAsync dispatcher;

    @SuppressWarnings("unused")
    private GlobalConstants constants;

    private GlobalMessages messages;

    private ChannelTreeModel channelTreeModel;

    @Inject
    public ArticlesPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, GlobalConstants constants,
            GlobalMessages messages) {
        super(display, eventBus);
        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;

    }

    @Override
    protected void onBind() {

        registerHandler(eventBus.addHandler(ArticlesDeletedEvent.TYPE, new ArticlesDeletedEventHandler() {
            @Override
            public void onArticlesDeleted(ArticlesDeletedEvent event) {
                display.reloadData();
                Info.display(messages.success(), messages.articlesDeleted(event.getArticles().size()));
            }
        }));

        display.getAddButton().addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                eventBus.fireEvent(new AddArticleEvent(channelTreeModel.getId()));
            }
        });

        display.getDeleteButton().addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                removeArticles();
            }
        });

        display.getClearCacheButton().addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                clearCache();
            }
        });

        display.getGrid().addListener(Events.RowDoubleClick, new Listener<GridEvent<BeanModel>>() {
            public void handleEvent(GridEvent<BeanModel> se) {
                ArticleListModel m = se.getModel().getBean();
                eventBus.fireEvent(new EditArticleEvent(m.getId()));
            }
        });

        display.getGrid().getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BeanModel>() {

            @Override
            public void selectionChanged(SelectionChangedEvent<BeanModel> se) {

                if (se.getSelection().size() > 0) {
                    display.getDeleteButton().setEnabled(true);
                } else {
                    display.getDeleteButton().setEnabled(false);
                }
            }
        });

    }

    protected void clearCache() {

        dispatcher.execute(new ClearCache(), new AsyncCallback<ClearCacheResult>() {
            public void onFailure(Throwable caught) {
                MessageBox.alert(messages.error(), messages.clearCacheFailed(), null);
            }

            public void onSuccess(ClearCacheResult result) {
                Info.display(messages.success(), messages.cacheCleared());

            }

        });
    }

    protected void removeArticles() {

        List<BeanModel> models = display.getGrid().getSelectionModel().getSelectedItems();
        final List<Long> list = new ArrayList<Long>();
        for (BeanModel model : models) {
            ArticleListModel a = model.getBean();
            list.add(a.getId());
        }
        final Listener<MessageBoxEvent> l = new Listener<MessageBoxEvent>() {
            public void handleEvent(MessageBoxEvent ce) {
                if (Dialog.YES.equals(ce.getButtonClicked().getItemId())) {
                    doRemoveArticles(list);
                }
            }
        };

        if (list.size() > 0) {
            MessageBox.confirm(messages.confirmDelete(), messages.confirmDeleteArticles(list.size()), l);
        }

    }

    private void doRemoveArticles(final List<Long> list) {
        dispatcher.execute(new RemoveArticles(list), new AsyncCallback<RemoveArticlesResult>() {
            public void onFailure(Throwable caught) {
                MessageBox.alert(messages.error(), messages.deleteArticlesFailed(), null);
            }

            public void onSuccess(RemoveArticlesResult result) {
                eventBus.fireEvent(new ArticlesDeletedEvent(list));

            }

        });
    }

    @Override
    protected void onRevealDisplay() {
        if (null == channelTreeModel || channelTreeModel.getId() == null) {
            display.getAddButton().setEnabled(false);
        } else {
            display.getAddButton().setEnabled(true);
        }
        display.reloadData();
    }

    @Override
    protected void onUnbind() {

    }

    public void revealDisplay(ChannelTreeModel channelTreeModel) {
        this.channelTreeModel = channelTreeModel;

        revealDisplay();
    }

}
